<?php
//redis 分布式 锁 测试demo 测试场景 秒杀抢购商品

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$lockKey    = 'lock'; //设置锁KEY
$lockExpire = 10;  //设置锁的有效期为10秒

$status = true;
while ($status)
{
    //设置锁值为当前时间戳 + 有效期
    $lockValue = time() + $lockExpire;
    /**
     * 创建锁
     * 试图以$lockKey为key创建一个缓存,value值为当前时间戳
     * 由于setnx()函数只有在不存在当前key的缓存时才会创建成功
     * 所以，用此函数就可以判断当前执行的操作是否已经有其他进程在执行了
     * @var [type]
     */
    $lock = $redis->setnx($lockKey, $lockValue);

    /**
     * 满足两个条件中的一个即可进行操作
     * 1、上面一步创建锁成功;
     * 2、   1）判断锁的值（时间戳）是否小于当前时间    $redis->get()
     *      2）同时给锁设置新值成功    $redis->getset()
     */
    //代表上锁
    if(!empty($lock) || ($redis->get($lockKey) - time() < 0   &&  $redis->getSet($lockKey, $lockValue) - time() < 0))
    {

        //给锁设置生存时间
        $redis->expire($lockKey, $lockExpire);

        //执行抢购商品逻辑
        //do success

        echo "do success";


        //以上程序走完删除锁
        //检测锁是否过期，过期锁没必要删除
        if($redis->ttl($lockKey))
        {
            //代表 没过期的话 删除锁
            $redis->del($lockKey);
        }
        $status = false;
    }else
    {
        /**
         * 如果存在有效锁这里做相应处理
         *      等待当前操作完成再执行此次请求
         *      直接返回
         */
        sleep(2);//等待2秒后再尝试执行操作
    }
}


